package com.hc.springbootredis.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

//将Redis默认的二进制缓存方式改成json格式
@Configuration
public class RedisConfig {

    //自定义RedisTemplate 只针对API方式有效
    @Bean
    public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        //创建JSON序列化方式
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        //处理转化异常的情况
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        //设置序列化方式
        redisTemplate.setDefaultSerializer(serializer);
        return redisTemplate;
    }

    //Redis缓存管理器 只针对注解方式有效
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory){
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); //Value序列化规则
        RedisSerializer<String> redisSerializer = new StringRedisSerializer(); //Key序列化规则

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        RedisCacheConfiguration configuration = RedisCacheConfiguration
                .defaultCacheConfig()
                .entryTtl(Duration.ofDays(1)) //设置过期时间
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置Key序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))//设置Value序列化
                .disableCachingNullValues(); //设置null不序列化
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(configuration).build();
        return cacheManager;
    }
}
